home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
151-175
/
scopedisk168
/
tinytools
/
filtex
/
filtex.asm
< prev
next >
Wrap
Assembly Source File
|
1995-03-19
|
7KB
|
255 lines
; Filter non-text bytes from pipe stream.
INCLUDE "/include/init.i"
; Local Equs
; FilTex uses a buffer split into two 1000 byte parts, the first for writing,
; the last part for reading. Reads/Writes are HalfBufSize bytes large max.
DefaultThreshold EQU 4
BufSize EQU 2000 ; Keep this one < 32K
HalfBufSize EQU BufSize/2
; Variable storage
STRUCT ArgArray,(4+1)*4
LONG InputHandle
LONG StdOutput
WORD Threshold
SIZE
; Regs
WriteBufIndex EQUR D4
ReadBufIndex EQUR D5
ReadBytesLeft EQUR D6
LatestByte EQUR D7
BufferPtr EQUR A2
FilterTablePtr EQUR A3
ErrorStrPtr EQUR A4
; Start
STACK 4000
INIT
; Let ARP interpret the commandline
MOVE.L ComLineBase(GP),A0
MOVE.L ComLineSize(GP),D0
LEA HelpMsg(PC),A1
LEA ArgArray(GP),A2
LEA Template(PC),A3
MOVE.L A1,(A2)
CALL GADS
MOVE.L (A2),ErrorStrPtr
TST.L D0
BEQ ErrorExit
BMI ErrorExit
; Fetch & check the threshold value.
LEA BadThreshold(PC),ErrorStrPtr
MOVE.W #DefaultThreshold,Threshold(GP)
MOVE.L ArgArray+4(GP),A0
MOVE.L A0,D0
BEQ.S UseDefault
CALL Atol
BEQ ErrorExit
CMP.L #HalfBufSize,D0
BHI ErrorExit
MOVE.W D0,Threshold(GP)
BEQ ErrorExit
UseDefault:
; Check if the source is STDIN, if so open that.
MOVE.L ArgArray(GP),A0
LEA StdinID(PC),A1
CALL Strcmp
BNE.S NoStdin
CALL Input
MOVE.L D0,InputHandle(GP)
BRA.S InFileOpened
NoStdin:
; Else open a normal source file (Tracked)
LEA SourceOpenError(PC),ErrorStrPtr
MOVE.L ArgArray(GP),D1
MOVE.L #MODE_OLDFILE,D2
CALL ArpOpen
MOVE.L D0,InputHandle(GP)
BEQ ErrorExit
InFileOpened:
; Fetch the StdOutput
CALL Output
MOVE.L D0,StdOutput(GP)
; Alloc tracked mem for the read/write buffer.
LEA OutOfMem(PC),ErrorStrPtr
MOVE.L #BufSize+1,D0 ; add 1 to allow for LF termination
MOVEQ #0,D1
CALL ArpAllocMem
TST.L D0
BEQ ErrorExit
MOVE.L D0,BufferPtr
; Initialize for the filtered copy loop
LEA FilterTableBase(PC),FilterTablePtr
MOVEQ #0,WriteBufIndex
; Read next chunk of bytes.
DoNextRead:
LEA ReadError(PC),ErrorStrPtr
MOVEQ #0,ReadBufIndex
MOVE.W #HalfBufSize,ReadBufIndex
MOVE.L InputHandle(GP),D1
MOVE.L BufferPtr,D2
ADD.L ReadBufIndex,D2
MOVE.L ReadBufIndex,D3
CALL Read
MOVE.W D0,ReadBytesLeft
BMI ErrorExit
BEQ.S TryToWriteWriteBuffer
; Find text bytes.
CheckForTextBytes:
MOVEQ #0,LatestByte
MOVE.B 0(BufferPtr,ReadBufIndex.W),LatestByte
ADDQ.W #1,ReadBufIndex
SUBQ.W #1,ReadBytesLeft
TST.B 0(FilterTablePtr,LatestByte.W)
BEQ.S TryToWriteWriteBuffer
; Process text bytes
MOVE.B LatestByte,0(BufferPtr,WriteBufIndex.W)
ADDQ.W #1,WriteBufIndex
CMP.W #HalfBufSize,WriteBufIndex
BNE.S CheckReadBufStatus
; Check if the number of bytes to write equals or exceeds the threshold
TryToWriteWriteBuffer:
CMP.W Threshold(GP),WriteBufIndex
BLO.S NeLeWritezPas
; Check if string is null-terminated (if requested to do so)
TST.L ArgArray+12(GP) ; Check NULT switch
BEQ.S NoNullCheck
TST.B LatestByte
BNE.S NeLeWritezPas
NoNullCheck:
; Terminate write with a linefeed if needed & not prohibited
CMP.B #10,-1(BufferPtr,WriteBufIndex.W)
BEQ.S DoTheWrite
TST.L ArgArray+8(GP) ; Check NOLF switch
BNE.S DoTheWrite
MOVE.B #10,0(BufferPtr,WriteBufIndex.W)
ADDQ.W #1,WriteBufIndex
; The actual write to the StdOutput
DoTheWrite:
LEA WriteError(PC),ErrorStrPtr
MOVE.L StdOutput(GP),D1
MOVE.L BufferPtr,D2
MOVE.W WriteBufIndex,D3
EXT.L D3
CALL Write
CMP.L D0,D3
BNE.S ErrorExit
; Check if user hit ^C
SUB.L A1,A1
CALL CheckAbort
MOVE.L A1,ErrorStrPtr
TST.L D0
BNE.S ErrorExit
NeLeWritezPas:
; Reset the write buffer index.
MOVEQ #0,WriteBufIndex
; Check if no more read bytes left, if so read, exit if last read had zero length
; (An adjective, verb and a noun. YOU try 'n make a natural language interpreter!)
CheckReadBufStatus:
TST.W ReadBytesLeft
BNE CheckForTextBytes
CMP.W #HalfBufSize,ReadBufIndex
BNE DoNextRead
; Done, cleanup
Exit:
CLR.W ReturnCode(GP)
SUB.L ErrorStrPtr,ErrorStrPtr
ErrorExit:
; Display error string, if any, and exit
MOVE.L ErrorStrPtr,D0
BEQ.S NoErrorMsg
MOVE.L D0,A1
CALL Puts
NoErrorMsg:
RTS
; The string section
Template:
DC.B 'File/a,THRESH/k,NOLF/s,NULT/s',0
HelpMsg:
DC.B 'FilTex - filter out non-text.',10
DC.B 'Usage: FilTex <File | STDIN> [THRESH #] [NOLF] [NULT]',0
StdinID:
DC.B 'STDIN',0
BadThreshold:
DC.B 'Illegal threshold value',0
SourceOpenError:
DC.B 'Could not open source file',0
OutOfMem:
DC.B 'Out of memory!',0
ReadError:
DC.B 'Error while reading',0
WriteError:
DC.B 'Error while writing',0
CNOP 0,4
; This is the filtering array
DC.B 'TextTab:'
FilterTableBase:
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
DC.B 000,000,000,000,000,000,000,000,000,$09,$0A,000,000,000,000,000 ;0
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;1
DC.B ' ','!','"','#','$','%','&',$27,'(',')','*','+',',','-','.','/' ;2
DC.B '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?' ;3
DC.B 000,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O' ;4
DC.B 'P','Q','R','S','T','U','V','W','X','Y','Z','[','\',']','^','_' ;5
DC.B 000,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o' ;6
DC.B 'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',000 ;7
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;8
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;9
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;A
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;B
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;C
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;D
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;E
DC.B 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;F
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
END